home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / include / user / sync.h < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-28  |  6.8 KB  |  209 lines

  1. /*
  2.  * sync.h --
  3.  *
  4.  *     Typedefs and macros to support the use of monitors.
  5.  *      Clients use the macros to acquire and release monitor locks, and
  6.  *      to wait on and notify monitored condition variables.  Only Broadcast
  7.  *      semantics are supported for lock release; that is, all processes
  8.  *      waiting on a lock are made runnable when the locked is released.
  9.  *
  10.  * Copyright 1986, 1988, 1991 Regents of the University of California
  11.  * Permission to use, copy, modify, and distribute this
  12.  * software and its documentation for any purpose and without
  13.  * fee is hereby granted, provided that the above copyright
  14.  * notice appear in all copies.  The University of California
  15.  * makes no representations about the suitability of this
  16.  * software for any purpose.  It is provided "as is" without
  17.  * express or implied warranty.
  18.  *
  19.  *
  20.  * $Header: /user5/kupfer/spriteserver/include/user/RCS/sync.h,v 1.7 92/05/27 21:19:32 kupfer Exp $ SPRITE (Berkeley)
  21.  */
  22.  
  23. #ifndef _SYNCUSER
  24. #define _SYNCUSER
  25.  
  26. #include <sprite.h>
  27. #include <cthreads.h>
  28.  
  29. /* 
  30.  * Dummy definition for a user lock.  This is to keep the compiler happy 
  31.  * when dealing with programs that include Sprite server header files.  It
  32.  * needs to be fixed whenever we get around to supporting multi-threaded
  33.  * user programs.
  34.  */
  35.  
  36. typedef int Sync_UserLock;
  37.  
  38. #if !defined(KERNEL) && !defined(SPRITED)
  39. typedef Sync_UserLock Sync_Lock;
  40. #endif
  41.  
  42. /*
  43.  * Condition variables represent events that are associated with
  44.  * locks.  The operations on a condition variable are Sync_Wait and
  45.  * Sync_Broadcast. The lock must be acquired before a call to
  46.  * Sync_Wait is made.  The lock is released while a process waits on a
  47.  * condition, and is then re-acquired when the condition is notified
  48.  * via Sync_Broadcast.
  49.  * 
  50.  * For the Sprite server we basically just use a C Threads condition
  51.  * variable.  The "initialized" flag is used for compatibility with
  52.  * native Sprite code, which doesn't require that condition variables be 
  53.  * initialized before use.
  54.  */
  55.  
  56. typedef struct Sync_Condition {
  57.     struct condition condVar;
  58.     Boolean initialized;
  59.     Boolean dynamicName;    /* does c.v. name need freeing */
  60. } Sync_Condition;
  61.  
  62. /*
  63.  * Maximum number of prior locks that can exist for any type of lock. A prior
  64.  * lock is the last lock to be grabbed by the process grabbing the current 
  65.  * lock. Keeping track of the locks held by a process is done in the proc
  66.  * module. By knowing all the prior locks of a lock it is possible to 
  67.  * construct a tree representing the locking behavior of the system.
  68.  * SYNC_MAX_PRIOR places a limit on how many prior locks will be remembered
  69.  * for an individual lock.
  70.  */
  71.  
  72. #ifndef LOCKDEP
  73. #define SYNC_MAX_PRIOR 1
  74. #else
  75. #define SYNC_MAX_PRIOR 30
  76. #endif
  77.  
  78. /*
  79.  * This structure is used to pass locking statistics to user programs.
  80.  * One of these structures is needed per lock type.
  81.  */
  82. typedef struct {
  83.     int        inUse;                /* 1 if structure is valid  */
  84.     int        class;                /* 0 = semaphore, 1 = lock */
  85.     int        hit;                /* # times lock was grabbed */
  86.     int        miss;                /* # times lock was missed */
  87.     char    name[30];            /* name of lock */
  88.     int        priorCount;            /* # of prior locks  */
  89.     int        priorTypes[SYNC_MAX_PRIOR];    /* types of prior locks */
  90.     int        activeCount;            /* # active locks of type */
  91.     int        deadCount;            /* # dead locks of type */
  92.     int        spinCount;            /* # spins waiting for lock */
  93. } Sync_LockStat;
  94.  
  95.  
  96. /*
  97.  * ----------------------------------------------------------------------------
  98.  *
  99.  * Monitor Locks --
  100.  *
  101.  *    The following set of macros are used to emulate monitored
  102.  *    procedures of Mesa.  The Sprite style document has a complete
  103.  *    description of the conventions required to emulate a set
  104.  *    of monitored procedures; a summary is presented here.
  105.  *
  106.  *      The LOCK_MONITOR and UNLOCK_MONITOR macros depend on a constant
  107.  *      LOCKPTR.  LOCKPTR should be defined as the address of the lock
  108.  *      variable used to lock the monitor.  Something like the following
  109.  *      two lines of code should appear at the beginning of a file of
  110.  *      monitored procedures.
  111.  *
  112.  *    Sync_Lock modMonitorLock;
  113.  *    #define LOCKPTR (&modMonitorLock)
  114.  *
  115.  *    The pseudo-keywords INTERNAL and ENTRY denote internal and entry
  116.  *    procedures of a monitor.  INTERNAL procedures can only be called
  117.  *    when the monitor lock is held.  ENTRY procedures are procedures
  118.  *    that acquire the lock.  There may also be External procedures.
  119.  *    They are the default and there is no special keyword.  An External
  120.  *    procedure doesn't explicitly acquire the monitor lock, but may
  121.  *    call an ENTRY procedure.
  122.  *
  123.  * ----------------------------------------------------------------------------
  124.  */
  125.  
  126. /* XXX disable monitors for user code. */
  127. #ifdef SPRITED
  128. #define LOCK_MONITOR               (void) Sync_GetLock(LOCKPTR)
  129. #define UNLOCK_MONITOR             (void) Sync_Unlock(LOCKPTR)
  130. #else
  131. #define LOCK_MONITOR
  132. #define UNLOCK_MONITOR
  133. #endif
  134.  
  135. #define ENTRY
  136. #define INTERNAL
  137.  
  138.  
  139. /*
  140.  * ----------------------------------------------------------------------------
  141.  *
  142.  * Sync_Wait --
  143.  *
  144.  * Wait on a condition variable.  This can only be called while a lock
  145.  * is aquired because it is only safe to check global state while in a
  146.  * monitor.  This releases the monitor lock and makes the process sleep
  147.  * on the condition. The monitor lock is reacquired after the process 
  148.  * has been woken up.
  149.  *
  150.  * The address of the condition variable is used as the generic 'event'
  151.  * that the process blocks on.  The value of the condition variable is
  152.  * used to indicate if there is a process waiting on the condition.
  153.  *
  154.  * Results:
  155.  *    None.
  156.  *
  157.  * Side effects:
  158.  *    Put the process to sleep and release the monitor lock.
  159.  *
  160.  * ----------------------------------------------------------------------------
  161.  */
  162.  
  163. #define Sync_Wait(conditionPtr, wakeIfSignal) \
  164.     Sync_SlowWait(conditionPtr, LOCKPTR, wakeIfSignal)
  165.  
  166.  
  167. /*
  168.  * ----------------------------------------------------------------------------
  169.  *
  170.  * Sync_Broadcast --
  171.  *
  172.  *      Notify other processes that a condition has been met (this is 
  173.  *      the version for user processes only).
  174.  *
  175.  * Monitor Lock:
  176.  *    This routine needs to be called with the monitor lock held.
  177.  *    This ensures synchronous access to the conditionPtr->waiting flag.
  178.  *
  179.  * Results:
  180.  *    None.
  181.  *
  182.  * Side effects:
  183.  *    Make the processes waiting on the condition variable runnable.
  184.  *
  185.  * ----------------------------------------------------------------------------
  186.  */
  187.  
  188. #ifndef SPRITED
  189. #define Sync_Broadcast(conditionPtr) \
  190.     if (((Sync_Condition *)conditionPtr)->waiting == TRUE)  { \
  191.     (void)Sync_SlowBroadcast((unsigned int) conditionPtr, \
  192.       &((Sync_Condition *)conditionPtr)->waiting); \
  193.     }
  194. #endif
  195.  
  196. /*
  197.  * Exported procedures of the sync module for monitors.
  198.  */
  199.  
  200. #if !defined(KERNEL) && !defined(SPRITED)
  201. extern ReturnStatus    Sync_GetLock();
  202. extern ReturnStatus    Sync_Unlock();
  203. #endif
  204. extern ReturnStatus    Sync_SlowLock();
  205. extern ReturnStatus    Sync_SlowWait();
  206. extern ReturnStatus    Sync_SlowBroadcast();
  207.  
  208. #endif /* _SYNCUSER */
  209.